<template>
  <div>
    <div class="toolbox">
      <button @click="updateFirstRow">更新工位</button>
      <button @click="changeZoomLevel(1)">30分钟</button>
      <button @click="changeZoomLevel(2)">1小时</button>
      <button @click="changeZoomLevel(3)">4小时</button>
      <button @click="changeZoomLevel(4)">12小时</button>
      <button @click="changeZoomLevel(5)">天</button>
      <button @click="changeZoomLevel(6)">周</button>
      <button @click="changeZoomLevel(7)">月</button>
      <!-- <button @click="changeZoomLevel1(16)">16 日/小时 重</button>
      <button @click="changeZoomLevel1(17)">17 日/小时 重</button>
      <button @click="changeZoomLevel1(23)">23 月/周 重</button>
      <button @click="changeZoomLevel1(24)">24 月/周</button>
      <button @click="changeZoomLevel1(25)">25 月/周 重</button>
      <button @click="changeZoomLevel1(27)">27 月/周 重</button>
      <button @click="changeZoomLevel1(100)">100 月/周</button>
      <button @click="changeZoomLevel1(19)">19 月/周</button>
      <button @click="changeZoomLevel1(20)">20 月/周</button>
      <button @click="changeZoomLevel1(21)">21 月/周</button>
      <button @click="changeZoomLevel1(22)">22 月/周</button>
      <button @click="changeZoomLevel1(26)">26 月/周</button>
      <button @click="changeZoomLevel1(28)">28 月/周</button>
      <button @click="changeZoomLevel1(29)">29 月/周</button>
      <button @click="changeZoomLevel1(30)">30 月/周</button> -->
      
    </div>
    <div class="gstc-wrapper" ref="gstc"></div>
  </div>
</template>

<script>
import GSTC from "gantt-schedule-timeline-calendar";
import { Plugin as TimelinePointer } from "gantt-schedule-timeline-calendar/dist/plugins/timeline-pointer.esm.min.js";
import { Plugin as Selection } from "gantt-schedule-timeline-calendar/dist/plugins/selection.esm.min.js";
import { Plugin as ItemResizing } from "gantt-schedule-timeline-calendar/dist/plugins/item-resizing.esm.min.js";
import { Plugin as ItemMovement } from "gantt-schedule-timeline-calendar/dist/plugins/item-movement.esm.min.js";
import "gantt-schedule-timeline-calendar/dist/style.css";

let gstc, state;
// helper functions
// let canChangeRow = true;
// let canCollide = true;
// document.getElementById('can-change-row').addEventListener('change', function (el) {
//     canChangeRow = el.target.checked;
//   });
//   document
//   .getElementById('can-collide')
//   .addEventListener('change', function (el) {
//     canCollide = el.target.checked;
//   });
// function isCollision(item) {
//   const allItems = gstc.api.getAllItems();
//   for (const itemId in allItems) {
//     if (itemId === item.id) continue;
//     const currentItem = allItems[itemId];
//     if (currentItem.rowId === item.rowId) {
//       if (
//         item.time.start >= currentItem.time.start &&
//         item.time.start <= currentItem.time.end
//       )
//         return true;
//       if (
//         item.time.end >= currentItem.time.start &&
//         item.time.end <= currentItem.time.end
//       )
//         return true;
//       if (
//         item.time.start <= currentItem.time.start &&
//         item.time.end >= currentItem.time.end
//       )
//         return true;
//       if (
//         item.time.start >= currentItem.time.start &&
//         item.time.end <= currentItem.time.end
//       )
//         return true;
//     }
//   }
//   return false;
// }
// resize方法
function isItemResizable(item) {
  if (typeof item.resizable === 'boolean') return item.resizable;
  return true;
}

function limitTime(item, oldItem) {
  if (item.resizableFrom && item.time.start < item.resizableFrom) {
    item.time.start = item.resizableFrom;
  }
  if (item.resizableTo && item.time.end > item.resizableTo) {
    item.time.end = item.resizableTo;
  }
  if (item.resizableLength && item.resizablePeriod) {
    const actualDiff = GSTC.api
      .date(item.time.end)
      .diff(item.time.start, item.resizablePeriod, true);
    if (actualDiff > item.resizableLength) {
      const resizingFromStart = item.time.end === oldItem.time.end;
      if (resizingFromStart) {
        item.time.start = GSTC.api
          .date(item.time.end)
          .subtract(item.resizableLength, item.resizablePeriod) // -1 here because end of day - 3 days -> startOf day = almost 4 days
          .valueOf();
      } else {
        item.time.end = GSTC.api
          .date(item.time.start)
          .add(item.resizableLength, item.resizablePeriod)
          .valueOf();
      }
    }
  }
  return item;
}

function snapToTimeSeparately(item) {
  if (!item.snap) return item;
  const start = GSTC.api.date(item.time.start).startOf('day').add(10, 'hour');
  const end = GSTC.api.date(item.time.end).startOf('day').add(18, 'hour');
  item.time.start = start.valueOf();
  item.time.end = end.valueOf();
  // to change other properties than time we need to update item
  // because resizing-items plugin only works on time property
  state.update(
    `config.chart.items.${item.id}.label`,
    `From ${start.format('YYYY-MM-DD HH:mm')} to ${end.format(
      'YYYY-MM-DD HH:mm'
    )}`
  );
  return item;
}


/**
 * @returns { import("gantt-schedule-timeline-calendar").Rows }
 */
function generateRows() {
  const rows = {};
  rows[GSTC.api.GSTCID("1")] = {
    id: GSTC.api.GSTCID("1"),
    label: `工位1`,
  };
  rows[GSTC.api.GSTCID("2")] = {
    id: GSTC.api.GSTCID("2"),
    label: `工位2`,
  };
  rows[GSTC.api.GSTCID("3")] = {
    id: GSTC.api.GSTCID("3"),
    label: `工位3`,
  };
  rows[GSTC.api.GSTCID("4")] = {
    id: GSTC.api.GSTCID("4"),
    label: `工位4`,
  };
  rows[GSTC.api.GSTCID("5")] = {
    id: GSTC.api.GSTCID("5"),
    label: `工位5`,
  };
  rows[GSTC.api.GSTCID("6")] = {
    id: GSTC.api.GSTCID("6"),
    label: `工位6`,
  };
  rows[GSTC.api.GSTCID("7")] = {
    id: GSTC.api.GSTCID("7"),
    label: `工位7`,
  };
  rows[GSTC.api.GSTCID("8")] = {
    id: GSTC.api.GSTCID("8"),
    label: `工位8`,
  };
  // for(let i=0;i<100;i++){
  //   const id = GSTC.api.GSTCID(i.toString());
  //   rows[id]={
  //     id,
  //     label:`工位 ${i}`
  //   }
  // }
  return rows;
}

/**
 * @returns { import("gantt-schedule-timeline-calendar").Items }
 */
function generateItems() {
  const items = {};
  // let start = GSTC.api.date().startOf("hour").subtract(2, "hour");
  // for (let i = 0; i < 100; i++) {
  //   const id = GSTC.api.GSTCID(i.toString());
  //   const rowId = GSTC.api.GSTCID(Math.floor(Math.random() * 100).toString());
  //   start = start.add(1, "day");
  //   items[id] = {
  //     id,
  //     label: `Item ${i}`,
  //     rowId,
  //     time: {
  //       start: start.valueOf(),
  //       end: start.add(1, "day").endOf("day").valueOf(),
  //     },
  //   };
  // }
  items[GSTC.api.GSTCID("1")] = {
    id: GSTC.api.GSTCID("1"),
    label: `任务1 (已下发)`,
    rowId: GSTC.api.GSTCID("1"),
    style:{background:'#c8ede2',border:'1px solid #3dd27e'},
    time: {
      start: GSTC.api.date("2021-06-02 11:06:00").valueOf(),
      end: GSTC.api.date("2021-06-08 12:00:00").valueOf(),
    },
  };
  items[GSTC.api.GSTCID("2")] = {
    id: GSTC.api.GSTCID("2"),
    label: `任务2 (停机)`,
    rowId: GSTC.api.GSTCID("2"),
    style:{background:'#fcc1bd'},
    time: {
      start: GSTC.api.date("2020-12-02 11:06:00").valueOf(),
      end: GSTC.api.date("2021-01-18 12:00:00").valueOf(),
    },
  };
  items[GSTC.api.GSTCID("3")] = {
    id: GSTC.api.GSTCID("3"),
    label: `任务3 (暂停中)`,
    style:{background:'#facc70'},
    rowId: GSTC.api.GSTCID("3"),
    time: {
      start: GSTC.api.date("2021-06-03 11:06:00").valueOf(),
      end: GSTC.api.date("2021-06-04 12:00:00").valueOf(),
    },
  };
  items[GSTC.api.GSTCID("4")] = {
    id: GSTC.api.GSTCID("4"),
    label: `任务4 (实际)`,
    style:{background:'#3dd27e'},
    rowId: GSTC.api.GSTCID("5"),
    time: {
      start: GSTC.api.date("2021-04-12 04:12:00").valueOf(),
      end: GSTC.api.date("2021-05-27 05:27:00").valueOf(),
    },
  };
  items[GSTC.api.GSTCID("5")] = {
    id: GSTC.api.GSTCID("5"),
    label: `任务5 (未下发)`,
    style:{background:'#b6dafc'},
    rowId: GSTC.api.GSTCID("6"),
    time: {
      start: GSTC.api.date("2021-06-02 11:06:00").valueOf(),
      end: GSTC.api.date("2021-06-04 12:00:00").valueOf(),
    },
  };
  items[GSTC.api.GSTCID("6")] = {
    id: GSTC.api.GSTCID("6"),
    label: `任务6 (延期结束)`,
    style:{background:'#fd8781'},
    rowId: GSTC.api.GSTCID("6"),
    time: {
      start: GSTC.api.date("2021-06-01 10:00:00").valueOf(),
      end: GSTC.api.date("2021-06-06 12:00:00").valueOf(),
    },
  };
  items[GSTC.api.GSTCID("7")] = {
    id: GSTC.api.GSTCID("7"),
    label: `任务7 (已结束)`,
    rowId: GSTC.api.GSTCID("7"),
    style:{background:'#b0e378'},
    time: {
      start: GSTC.api.date("2021-08-08 08:08:00").valueOf(),
      end: GSTC.api.date("2021-10-10 10:10:00").valueOf(),
    },
  };
  return items;
}

const weeks = [
  {
    zoomTo: 100, // we want to display this format for all zoom levels until 100
    period: 'week',
    periodIncrement: 1,
    classNames: ['showOneLine gstc-date-left'],
    format({ timeStart,timeEnd}) {
      return `${timeStart.format('YYYY MM DD')} ~ ${timeEnd.format('YYYY MM DD')}` ; // full list of formats: https://day.js.org/docs/en/display/format
    },
  },
];
const weekDays = [  
  {
    zoomTo: 100,
    period: 'day',
    periodIncrement: 1,
    main: true, // we want grid to be divided by this period = day
    format({ timeStart }) {
      return timeStart.format('dd');
    },
  }
];
const months = [
  {
    zoomTo: 100, // we want to display this format for all zoom levels until 100
    period: 'month',
    // main: true, // we want grid to be divided by this period = day
    classNames: ['gstc-date-medium gstc-date-left'],
    format({ timeStart }) {
      return timeStart.format('YYYY-MM'); // full list of formats: https://day.js.org/docs/en/display/format
    },
  },
];
const monthDays = [
  {
    zoomTo: 100,
    period: 'day',
    periodIncrement: 1,
    main: true, // we want grid to be divided by this period = day
    format({ timeStart }) {
      return timeStart.format('DD');
    },
  }
];
const days = [
  {
    zoomTo: 100,
    period: 'day',
    periodIncrement: 1,
    // main: true, // we want grid to be divided by this period = day
    classNames: ['gstc-date-medium gstc-date-left'],
    format({ timeStart }) {
      return timeStart.format('YYYY MM DD (dddd)');
    },
  }
];
const twelvehours = [
  {
    zoomTo: 100,
    period: 'hour',
    main: true,
    periodIncrement: 12,
    classNames: ['gstc-date-center'],
    format({ timeStart }) {
      return timeStart.format('HH:mm');
    },
  },
];
const fourhours = [
  {
    zoomTo: 100,
    period: 'hour',
    main: true,
    periodIncrement: 4,
    classNames: ['gstc-date-center'],
    format({ timeStart }) {
      return timeStart.format('HH:mm');
    },
  },
];
const hours = [
  {
    zoomTo: 16,
    period: 'hour',
    main: true,
    periodIncrement: 1,
    classNames: ['gstc-date-center'],
    format({ timeStart }) {
      return timeStart.format('HH:mm');
    },
  },
];
const minutes = [
  {
    zoomTo: 16,
    period: 'minute',
    main: true,
    periodIncrement: 30,
    classNames: ['gstc-date-center'],
    format({ timeStart }) {
      return timeStart.format('HH:mm');
    },
  },
];




// function onCellCreate({ vido }) {
//   return vido.html`<div class="my-grid-cell-content" ></div>`;
// }
// function onGridCellClick(row, time) {
//   alert(
//     'Cell ' +
//       GSTC.api.sourceID(row.id) +
//       ' ' +
//       time.leftGlobalDate.format('YYYY-MM-DD') +
//       ' clicked!'
//   );
// }

const movementPluginConfig = {
  events: {
    onStart({ items }) {
      console.log("开始移动", items.after);
      return items.after;
    },
    onMove({ items }) {
      console.log("移动中", items);
      if(!this.canEnd){
        this.canEnd = true
      }
      return items.before.map((beforeMovementItem, index) => {
        const afterMovementItem = items.after[index];
        const myItem = GSTC.api.merge({}, afterMovementItem);
        return myItem;
      });
    },
    onEnd({ items }) {
      if(this.canEnd){
        console.log("移动结束", items);
        this.canEnd = false
      }
      return items.after;

    },
  },
  // snapToTime: {
  //   start({ startTime, endTime }) {
  //     console.log(endTime,'时间--------------开始时间',startTime);
  //     return startTime.startOf('day').add(12, 'hour');
  //   },
  // },
};
const resizingPluginConfig = {
      events: {
        onStart({ items }) {
          console.log('开始拉动', items.after);
          this.canEnd = true
          return items.after;
        },
        onResize({ items }) {
          console.log('拉动中');
          const filtered = items.after
            .map((item, index) => {
              if (!isItemResizable(item)) {
                return items.before[index];
              }
              return item;
            })
            .map((item, index) => limitTime(item, items.before[index]))
            .map((item) => snapToTimeSeparately(item));
          return filtered;
        },
        onEnd({ items }) {
          if(this.canEnd){
            console.log('拉动结束', items);
          }
            return items.after;
        },
      },
      snapToTime: {
        start({ startTime }) {
          // reset default period snapping behavior
          // if you want custom snapping for all items out of the box - you can do it here
          // like: return startTime.startOf('day').add(8,'hour');
          return startTime;
        },
        end({ endTime }) {
          // reset default period snapping behavior
          return endTime;
        },
      },
    }


export default {
  name: "GSTC",
  mounted() {
    /**
     * @type { import("gantt-schedule-timeline-calendar").Config }
     */
    // class ResizingItemClassAction {
    //   update(element, data) {
    //     const hasClass = element.classList.contains('resizing');
    //     if (data.item.isResizing && !hasClass) {
    //       element.classList.add('resizing');
    //     } else if (!data.item.isResizing && hasClass) {
    //       element.classList.remove('resizing');
    //     }
    //   }
    // }
    // class MovingItemClassAction {
    //   update(element, data) {
    //     const hasClass = element.classList.contains("moving");
    //     if (data.item.isMoving && !hasClass) {
    //       element.classList.add("moving");
    //     } else if (!data.item.isMoving && hasClass) {
    //       element.classList.remove("moving");
    //     }
    //   }
    // }
    const config = {
      licenseKey:
        "====BEGIN LICENSE KEY====\nXOfH/lnVASM6et4Co473t9jPIvhmQ/l0X3Ewog30VudX6GVkOB0n3oDx42NtADJ8HjYrhfXKSNu5EMRb5KzCLvMt/pu7xugjbvpyI1glE7Ha6E5VZwRpb4AC8T1KBF67FKAgaI7YFeOtPFROSCKrW5la38jbE5fo+q2N6wAfEti8la2ie6/7U2V+SdJPqkm/mLY/JBHdvDHoUduwe4zgqBUYLTNUgX6aKdlhpZPuHfj2SMeB/tcTJfH48rN1mgGkNkAT9ovROwI7ReLrdlHrHmJ1UwZZnAfxAC3ftIjgTEHsd/f+JrjW6t+kL6Ef1tT1eQ2DPFLJlhluTD91AsZMUg==||U2FsdGVkX1/SWWqU9YmxtM0T6Nm5mClKwqTaoF9wgZd9rNw2xs4hnY8Ilv8DZtFyNt92xym3eB6WA605N5llLm0D68EQtU9ci1rTEDopZ1ODzcqtTVSoFEloNPFSfW6LTIC9+2LSVBeeHXoLEQiLYHWihHu10Xll3KsH9iBObDACDm1PT7IV4uWvNpNeuKJc\npY3C5SG+3sHRX1aeMnHlKLhaIsOdw2IexjvMqocVpfRpX4wnsabNA0VJ3k95zUPS3vTtSegeDhwbl6j+/FZcGk9i+gAy6LuetlKuARjPYn2LH5Be3Ah+ggSBPlxf3JW9rtWNdUoFByHTcFlhzlU9HnpnBUrgcVMhCQ7SAjN9h2NMGmCr10Rn4OE0WtelNqYVig7KmENaPvFT+k2I0cYZ4KWwxxsQNKbjEAxJxrzK4HkaczCvyQbzj4Ppxx/0q+Cns44OeyWcwYD/vSaJm4Kptwpr+L4y5BoSO/WeqhSUQQ85nvOhtE0pSH/ZXYo3pqjPdQRfNm6NFeBl2lwTmZUEuw==\n====END LICENSE KEY====",
      plugins: [
        TimelinePointer(),
        Selection(),
        ItemResizing(resizingPluginConfig),
        // ItemMovement()
        ItemMovement(movementPluginConfig),
      ],
      list: {
        columns: {
          data: {
            [GSTC.api.GSTCID("id")]: {
              id: GSTC.api.GSTCID("id"),
              width: 40,
              data: ({ row }) => GSTC.api.sourceID(row.id),
              header: {
                content: "序号",
              },
            },
            [GSTC.api.GSTCID("label")]: {
              id: GSTC.api.GSTCID("label"),
              width: 150,
              data: "label",
              header: {
                content: "工号",
              },
            },
            // [GSTC.api.GSTCID('another')] :{
            //   id:GSTC.api.GSTCID('another'),
            //   width: 100,
            //   data:'another',
            //   header:{
            //     content: '加一个'
            //   }
            // }
          },
          minWidth: 200,
        },
        rows: generateRows(),
      },
      chart: {
        items: generateItems(),
        time: {
          from: GSTC.api.date("2021-05-27").valueOf(),
          to: GSTC.api.date("2021-06-31").valueOf(),
          // zoom:16

        },
        calendarLevels:[months,monthDays],
        grid: {
          cell: {
            // onCreate:[onCellCreate]
          },
        },
      },
      locale: {
        name: "zh-cn",
        weekdays: "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
        weekdaysShort: "周日_周一_周二_周三_周四_周五_周六".split("_"),
        weekdaysMin: "日_一_二_三_四_五_六".split("_"),
        months: "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split(
          "_"
        ),
        monthsShort: "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split(
          "_"
        ),
        ordinal: (number, period) => {
          switch (period) {
            case "W":
              return `${number}周`;
            default:
              return `${number}日`;
          }
        },
        weekStart: 1,
        yearStart: 4,
        formats: {
          LT: "HH:mm",
          LTS: "HH:mm:ss",
          L: "YYYY/MM/DD",
          LL: "YYYY年M月D日",
          LLL: "YYYY年M月D日Ah点mm分",
          LLLL: "YYYY年M月D日ddddAh点mm分",
          l: "YYYY/M/D",
          ll: "YYYY年M月D日",
          lll: "YYYY年M月D日 HH:mm",
          llll: "YYYY年M月D日dddd HH:mm",
        },
        relativeTime: {
          future: "%s内",
          past: "%s前",
          s: "几秒",
          m: "1 分钟",
          mm: "%d 分钟",
          h: "1 小时",
          DD: "%d 小时",
          d: "1 天",
          dd: "%d 天",
          M: "1 个月",
          MM: "%d 个月",
          y: "1 年",
          yy: "%d 年",
        },
        meridiem: (hour, minute) => {
          const hm = hour * 100 + minute;
          if (hm < 600) {
            return "凌晨";
          } else if (hm < 900) {
            return "早上";
          } else if (hm < 1100) {
            return "上午";
          } else if (hm < 1300) {
            return "中午";
          } else if (hm < 1800) {
            return "下午";
          }
          return "晚上";
        },
      },
      // actions: {
      //   "chart-timeline-items-row-item": [MovingItemClassAction],
      // },
    };

    // let GSTCState = (window.state = GSTC.api.stateFromConfig(config));

    // watch item movement plugin data and set isResizing property to an item for ResizingItemClassAction
    // GSTCState.subscribe("config.plugin.ItemMovement", (itemMovement) => {
    //   if (!itemMovement || !itemMovement.item) return;
    //   state.update(
    //     `config.chart.items.${itemMovement.item.id}.isMoving`,
    //     itemMovement.item.moving
    //   );
    // });

    state = GSTC.api.stateFromConfig(config);
    //   setTimeout(() => {
    //     // change zoom after 4sec
    //     state.update('config.chart.time.zoom', (item) => {item = 21; return item});
    //     console.log('更新');
    // }, 2000);

    gstc = GSTC({
      element: this.$refs.gstc,
      state,
    });
  },

  beforeUnmount() {
    if (gstc) gstc.destroy();
  },  
  data(){
    return{
      canEnd : false
    }
  },

  methods: {
    updateFirstRow() {
      state.update(`config.list.rows.${GSTC.api.GSTCID("1")}`, (row) => {
        row.label = "更新工位";
        return row;
      });
    },

    changeZoomLevel(num) {
      state.update(`config.chart.time.zoom`,0)
      if(num == 1){
        console.log('30mm');
        state.update(`config.chart.calendarLevels`,[days,minutes])
        state.update(`config.chart.time.zoom`,15)
      } else if (num == 2){
        console.log('1hour');
        state.update(`config.chart.calendarLevels`,[days,hours])
        state.update(`config.chart.time.zoom`,16)
      } else if (num == 3){
        console.log('4hour');

        state.update(`config.chart.calendarLevels`,[days,fourhours])
        state.update(`config.chart.time.zoom`,18)
      } else if (num == 4){
        console.log('12hour');

        state.update(`config.chart.calendarLevels`,[days,twelvehours])
        state.update(`config.chart.time.zoom`,19)
      } else if (num == 5){
        console.log('day');
        
        state.update(`config.chart.calendarLevels`,[months,monthDays])
        state.update(`config.chart.time.zoom`,21)
      } else if (num == 6){
        console.log('week');
        state.update(`config.chart.calendarLevels`,[weeks,weekDays])
        state.update(`config.chart.time.zoom`,21)
      } else if (num == 7){
        console.log('month');
        state.update(`config.chart.calendarLevels`,[months,monthDays])
        state.update(`config.chart.time.zoom`,22)
      }
    },
    changeZoomLevel1(num) {
      state.update(`config.chart.time.zoom`,num)
    },

  },
};
</script>
<style scoped>
.gstc-component {
  margin: 0;
  padding: 0;
}
.toolbox {
  padding: 10px;
}
.gstc__chart-calendar-date{
  justify-content: center !important;
}
.showOneLine{
  overflow: hidden;
  text-overflow:ellipsis;
  white-space: nowrap;
}
</style>